import { BrowserWindow } from 'electron';
import { asyncChannels, replyOf } from './asyncChannels'
import { asyncChannel, exists } from './util'
import { listTemplates, Template } from './template'
import { MysqlDialect } from './db/mysql-dialect'
import { ModuleConfig } from './java/module-config'
import * as path from 'path'
import { JavaGenerator } from './java/java-generator'
import { FileWriter } from './java/file-writer'

export function codeListener(window: BrowserWindow) {
    templates(asyncChannels.codeGeneratorTemplates)
    checkDb(asyncChannels.codeGeneratorCheckDb)
    checkModule(asyncChannels.codeGeneratorCheckModule)
    generateCode(asyncChannels.codeGeneratorRun)
}

function templates(channel: string) {
    asyncChannel(channel, replyOf(channel), async (event, uid, args) => {
        return await listTemplates();
    })
}

function checkDb(channel: string) {
    asyncChannel(channel, replyOf(channel), async (event, uid, config) => {
        const dialect = new MysqlDialect(config)
        return await dialect.tables()
    })
}

function checkModule(channel: string) {
    asyncChannel(channel, replyOf(channel), async (event, uid, config: ModuleConfig) => {
        if (config.projectRoot && config.moduleName) {
            const p = path.resolve(config.projectRoot, config.moduleName)
            return !await exists(p)
        }
        return false
    })
}

function generateCode(channel: string) {
    asyncChannel(channel, replyOf(channel), async (event, uid, temp: Template, config: ModuleConfig) => {
        if (await exists(path.resolve(config.projectRoot, config.moduleName))) {
            throw new Error('模块目录已存在')
        }
        const template = (await listTemplates()).find(v => v.name === temp.name)
        if (!template) {
            throw new Error(`找不到模板: ${temp.name}`)
        }
        const generator = new JavaGenerator(config)
        const writer = new FileWriter()
        const res = await generator.generate(template)
        for (const r of res) {
            await writer.write(r)
        }
        return true
    })
}
